Ansibleでリモート先にsimplejsonをインストールするときのメモ
はじめに
パネポン対戦者絶賛募集中の横山です。 今回はちょっとしたTipsでsimplejsonが入ってないリモート環境にAnsible+yumを使って、simplejsonをインストールメモです。
前提
今回は検証用にvagrantを使い確認しました。
- ホスト
- Mac+Ansibleインストール済み
- インストール手順の参考: AWSチーム社内勉強会「Ansible」レポート
- Mac+Ansibleインストール済み
- リモート
- Vagrant+CentOS5.6(boxはVagrantbox.es の Minimal CentOS 5.6 を使用)
準備
boxを登録します。
$ vagrant box add centos5 http://dl.dropbox.com/u/9227672/centos-5.6-x86_64-netinstall-4.1.6.box vagrant box add centos6 http://dl.dropbox.com/u/9227672/centos-5.6-x86_64-netinstall-4.1.6.box ==> box: Adding box 'centos5' (v0) for provider: box: Downloading: http://dl.dropbox.com/u/9227672/centos-5.6-x86_64-netinstall-4.1.6.box box: Progress: 13% (Rate: 4092k/s, Estimated time remaining: 0:02:15)
==> box: Adding box 'centos5' (v0) for provider: box: Downloading: http://dl.dropbox.com/u/9227672/centos-5.6-x86_64-netinstall-4.1.6.box ==> box: Successfully added box 'centos5' (v0) for 'virtualbox'!
vagrant initをしてVagrantfileを作成します。
$ Vagrant init
Vagrantfileの中で先ほど追加したBoxを指定します。
$ vim Vagrantfile # config.vm.box = "Base" ↓ config.vm.box = "centos5"
VMを起動させます。
$ vagrant up
sshの情報を~/.ssh/configに登録したら準備完了です。
$ vagrant ssh-config --host test Host test HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/yokoyamafumihito/work/vagrant/test-centos5/.vagrant/machines/default/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL
$ vagrant ssh-config --host test >> ~/.ssh/config
結果
とりあえず、紆余曲折を経てこうなりました
- playbook.yml
- hosts: all sudo: True gather_facts: no tasks: - name: install python-simplejson raw: yum install -y python-simplejson
- hosts
test
- 実行画面
$ ansible-playbook -i hosts playbook.yml PLAY [all] ******************************************************************** TASK: [install python-simplejson] ********************************************* ok: [test] PLAY RECAP ******************************************************************** test : ok=1 changed=0 unreachable=0 failed=0
過程
とりあえず素直に書いた。
- hosts: all sudo: True tasks: - name: install python-simplejson yum: name=python-simplejson state=present
$ ansible-playbook -i hosts playbook.yml PLAY [all] ******************************************************************** GATHERING FACTS *************************************************************** failed: [test] => {"failed": true, "parsed": false} SUDO-SUCCESS-eqgrtgvmrgwqagqelneaupfktufktwse Error: ansible requires a json module, none found! TASK: [install python-simplejson] ********************************************* FATAL: no hosts matched or all hosts have already failed -- aborting PLAY RECAP ******************************************************************** to retry, use: --limit @/Users/yokoyamafumihito/playbook.retry test : ok=0 changed=0 unreachable=0 failed=1
ダメだったのでshellとrawを試した。
- hosts: all sudo: True tasks: - name: install python-simplejson shell: yum install -y python-simplejson
$ ansible-playbook -i hosts playbook.yml PLAY [all] ******************************************************************** GATHERING FACTS *************************************************************** failed: [test] => {"failed": true, "parsed": false} SUDO-SUCCESS-gqkrwgeyymwfokfuohjxtqrrjzevgkhq Error: ansible requires a json module, none found! TASK: [install python-simplejson] ********************************************* FATAL: no hosts matched or all hosts have already failed -- aborting PLAY RECAP ******************************************************************** to retry, use: --limit @/Users/yokoyamafumihito/playbook.retry test : ok=0 changed=0 unreachable=0 failed=1
- hosts: all sudo: True tasks: - name: install python-simplejson raw: yum install -y python-simplejson
$ ansible-playbook -i hosts playbook.yml PLAY [all] ******************************************************************** GATHERING FACTS *************************************************************** failed: [test] => {"failed": true, "parsed": false} SUDO-SUCCESS-omxeipeafvujdfetwooodupdrgatiwgb Error: ansible requires a json module, none found! TASK: [install python-simplejson] ********************************************* FATAL: no hosts matched or all hosts have already failed -- aborting PLAY RECAP ******************************************************************** to retry, use: --limit @/Users/yokoyamafumihito/playbook.retry test : ok=0 changed=0 unreachable=0 failed=1
ダメでした。梶さんに相談したら AnsibleでCiscoルータのIOSバージョン情報を一括取得してみた の中でコマンドだけを投げる例があるということで参考にさせてもらった。 この時初めて、gather_factsの存在を知る。
参考
factに関しては上記がわかりやすいと思いました。
gather_factsの項目の単体実行は以下のようになります。
- simplejsonインストール前
$ ansible all -m setup -i hosts test | FAILED >> { "failed": true, "msg": "Error: ansible requires a json module, none found!", "parsed": false }
- simplejsonインストール後
$ ansible all -m setup -i hosts test | success >> { "ansible_facts": { "ansible_all_ipv4_addresses": [ "10.0.2.15" ], "ansible_all_ipv6_addresses": [ "fe80::a00:27ff:fe09:d64" ], "ansible_architecture": "x86_64", "ansible_bios_date": "NA", "ansible_bios_version": "NA", "ansible_cmdline": { "divider": "10", "notsc": true, "ro": true, "root": "/dev/VolGroup00/LogVol00" }, "ansible_date_time": { "date": "2015-02-20", "day": "20", "epoch": "1424416835", "hour": "02", "iso8601": "2015-02-20T07:20:35Z", "iso8601_micro": "2015-02-20T07:20:35.%fZ", "minute": "20", "month": "02", "second": "35", "time": "02:20:35", "tz": "EST", "tz_offset": "-0500", "weekday": "Friday", "year": "2015" }, "ansible_default_ipv4": { "address": "10.0.2.15", "alias": "eth0", "gateway": "10.0.2.2", "interface": "eth0", "macaddress": "08:00:27:09:0d:64", "mtu": 1500, "netmask": "255.255.255.0", "network": "10.0.2.0", "type": "ether" }, "ansible_default_ipv6": {}, "ansible_devices": { "hdc": { "holders": [], "host": "", "model": null, "partitions": {}, "removable": "1", "rotational": null, "scheduler_mode": "cfq", "sectors": "8388604", "sectorsize": 512, "size": "4.00 GB", "support_discard": null, "vendor": null }, "sda": { "holders": [], "host": "", "model": "VBOX HARDDISK", "partitions": { "sda1": { "sectors": "208782", "sectorsize": 512, "size": "101.94 MB", "start": "63" }, "sda2": { "sectors": "20547135", "sectorsize": 512, "size": "9.80 GB", "start": "208845" } }, "removable": "0", "rotational": null, "scheduler_mode": "cfq", "sectors": "20766720", "sectorsize": 512, "size": "9.90 GB", "support_discard": null, "vendor": "ATA" } }, "ansible_distribution": "CentOS", "ansible_distribution_major_version": "5", "ansible_distribution_release": "Final", "ansible_distribution_version": "5.6", "ansible_domain": "ap-northeast-1.compute.internal", "ansible_env": { "HOME": "/home/vagrant", "LANG": "en_US.UTF-8", "LC_CTYPE": "en_US.UTF-8", "LOGNAME": "vagrant", "MAIL": "/var/mail/vagrant", "PATH": "/usr/local/bin:/bin:/usr/bin", "PWD": "/home/vagrant", "SHELL": "/bin/bash", "SHLVL": "2", "SSH_CLIENT": "10.0.2.2 56061 22", "SSH_CONNECTION": "10.0.2.2 56061 10.0.2.15 22", "SSH_TTY": "/dev/pts/1", "TERM": "xterm-256color", "USER": "vagrant", "_": "/usr/bin/python" }, "ansible_eth0": { "active": true, "device": "eth0", "ipv4": { "address": "10.0.2.15", "netmask": "255.255.255.0", "network": "10.0.2.0" }, "ipv6": [ { "address": "fe80::a00:27ff:fe09:d64", "prefix": "64", "scope": "link" } ], "macaddress": "08:00:27:09:0d:64", "module": "e1000", "mtu": 1500, "promisc": false, "type": "ether" }, "ansible_fips": false, "ansible_form_factor": "NA", "ansible_fqdn": "ip-10-0-2-15.ap-northeast-1.compute.internal", "ansible_hostname": "ip-10-0-2-15", "ansible_interfaces": [ "sit0", "lo", "eth0" ], "ansible_kernel": "2.6.18-238.el5", "ansible_lo": { "active": true, "device": "lo", "ipv4": { "address": "127.0.0.1", "netmask": "255.0.0.0", "network": "127.0.0.0" }, "ipv6": [ { "address": "::1", "prefix": "128", "scope": "host" } ], "mtu": 16436, "promisc": false, "type": "loopback" }, "ansible_machine": "x86_64", "ansible_memfree_mb": 843, "ansible_memtotal_mb": 1001, "ansible_mounts": [ { "device": "/dev/mapper/VolGroup00-LogVol00", "fstype": "ext3", "mount": "/", "options": "rw", "size_available": 7575445504, "size_total": 9100992512 }, { "device": "/dev/sda1", "fstype": "ext3", "mount": "/boot", "options": "rw", "size_available": 85000192, "size_total": 103512064 } ], "ansible_nodename": "ip-10-0-2-15.ap-northeast-1.compute.internal", "ansible_os_family": "RedHat", "ansible_pkg_mgr": "yum", "ansible_processor": [ "GenuineIntel", "Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz", "GenuineIntel", "Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz", "GenuineIntel", "Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz" ], "ansible_processor_cores": 3, "ansible_processor_count": 1, "ansible_processor_threads_per_core": 1, "ansible_processor_vcpus": 3, "ansible_product_name": "NA", "ansible_product_serial": "NA", "ansible_product_uuid": "NA", "ansible_product_version": "NA", "ansible_python_version": "2.4.3", "ansible_selinux": { "status": "disabled" }, "ansible_sit0": { "active": false, "device": "sit0", "macaddress": "00:00:00:00", "mtu": 1480, "promisc": false }, "ansible_ssh_host_key_dsa_public": "AAAAB3NzaC1kc3MAAACBAOct9HY8HNBInGPNS9IWx8nYunpwI7tgmnIMTnRNXslEzXdztefKsvwGi5AyzEAzZ", "ansible_ssh_host_key_rsa_public": "AAAABb+AHqVP3ZOVpmxOj6am9MS2R7Bb2G01Tlo4Iri9//Zi77WGYNrBvbQKG6rYUruUpfvWXz2LpeVD2empb0lu/FKBSA+XWliKJ57QN59pm+/sEODcnx5IVmw==", "ansible_swapfree_mb": 1055, "ansible_swaptotal_mb": 1055, "ansible_system": "Linux", "ansible_system_vendor": "NA", "ansible_user_id": "vagrant", "ansible_userspace_architecture": "x86_64", "ansible_userspace_bits": "64", "ansible_virtualization_role": "NA", "ansible_virtualization_type": "NA", "module_setup": true }, "changed": false }
gather_factsとはなんぞということで、simplejsonインストール後に試すと、リモートホストの特定情報が取れるらしい。 そのgather_factsの値がDefaultでONのため、先の「raw」と「shell」どちら共NGだった模様。 以下、検証。
- gather_facts: no、shellの場合
- hosts: all sudo: True gather_facts: no tasks: - name: install python-simplejson shell: yum install -y python-simplejson
$ ansible-playbook -i hosts playbook.yml PLAY [all] ******************************************************************** TASK: [install python-simplejson] ********************************************* failed: [test] => {"failed": true, "parsed": false} SUDO-SUCCESS-yrdgyohnnhafomywzzlmvckghyjyvqzr Error: ansible requires a json module, none found! FATAL: all hosts have already failed -- aborting PLAY RECAP ******************************************************************** to retry, use: --limit @/Users/yokoyamafumihito/playbook.retry test : ok=0 changed=0 unreachable=0 failed=1
- gather_facts: no、rawの場合
- hosts: all sudo: True gather_facts: no tasks: - name: install python-simplejson raw: yum install -y python-simplejson
$ ansible-playbook -i hosts playbook.yml PLAY [all] ******************************************************************** TASK: [install python-simplejson] ********************************************* ok: [test] PLAY RECAP ******************************************************************** test : ok=1 changed=0 unreachable=0 failed=0
まとめ
以上のことからActionの「shell」の結果はjsonで返して、「raw」はそのまま返ってくるものと推測出来ます。
gather_factsとか、rawとshellの違いとかが知れてよかったと思います。 今後Python2.4の入った環境自体少なくなるでしょうが、古い環境に一斉に「どんっ!」と入れるときのためのメモです。